/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <condition_variable>
#include <cstdint>
#include <string>
#include <future>
#include <memory>
#include <mutex>
#include <queue>
#include <shared_mutex>
#include <unordered_map>
#include <unordered_set>

#include <refbase.h>

#include "platform/ohos/rs_irender_service.h"
#include "../render_service_base/include/screen_manager/screen_types.h"

namespace OHOS {
namespace Rosen {
using ScreenChangeCallback = std::function<void(ScreenId, ScreenEvent, ScreenChangeReason)>;
class RSRenderProcessServiceManager : public RefBase {
public:
    RSRenderProcessManager(sptr<RSScreenManager> screenManager_);
    ~RSRenderProcessManager() noexcept = default;

    inline std::vector<std::string> Split(const std::string& str, const std::string& sep);
    std::vector<const char*> FormatCmd(const std::vector<std::string>& cmd);
    int32_t ForkExecChildProcess(const int32_t* pipeFd, int32_t count, const std::vector<const char*>& args);
    int32_t ForkExec(const std::string& command, ScreenId screenId, std::string* out);

    sptr<RSIRenderProcessConnection> GetRenderProcessConnectionProxy(pid_t pid);
    pid_t GetRenderProcessPid(ScreenId screenId);
    void SetRenderProcessConnectionProxy(pid_t pid, sptr<RSIRenderProcessConnection> conn);

private:
    mutable std::mutex mutex_;

    class RSScreenChangeHandler : public RSIScreenChangeCallback {
    public:
        explicit RSScreenChangeHandler(ScreenChangeCallback connectCallback) { this->connectCallback_ = connectCallback; }
        ~RSScreenChangeHandler() noexcept = default;

        void OnScreenChanged(ScreenId id, ScreenEvent event,
            ScreenChangeReason reason = ScreenChangeReason::DEFAULT) override;
        
        sptr<IRemoteObject> AsObject() override { return nullptr; }
    
    private:
        ScreenChangeCallback connectCallback_;
    };

    std::unordered_map<ScreenId, pid_t> screenId2RenderProcess_;
    std::unordered_map<pid_t, sptr<RSIRenderProcessConnection>> renderProcessConnections_;
    sptr<RSScreenManager> screenManager_;
    sptr<RSScreenChangeHandler> screenHandler_;
};
} // namespace Rosen
} // namespace OHOS